package com.lonely.order.support.synchronizer.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lonely.common.exception.BusinessException;
import com.lonely.order.domain.dto.api.ClothCostFeeDetail;
import com.lonely.order.domain.dto.api.ClothCostFeeItem;
import com.lonely.order.domain.dto.api.QueryProduceOrderInfoByIdResDTO;
import com.lonely.order.domain.entity.SysOrderPart;
import com.lonely.order.domain.entity.SysOrderProcess;
import com.lonely.order.domain.entity.SysOrderProcessItem;
import com.lonely.order.service.IOrderProcessItemService;
import com.lonely.order.service.IOrderProcessService;
import com.lonely.order.support.synchronizer.SynchronizerOrderContext;
import com.lonely.order.threadlocals.OrderSynchronizedThreadLocal;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author : 黄志标
 * @date: 2025/7/31 15:30
 * @description: 同步订单工序服务
 */
@Service
@Slf4j
public class SynchronizerOrderProcessService {

    @Autowired
    private IOrderProcessService orderProcessService;

    @Autowired
    private IOrderProcessItemService orderProcessItemService;

    /**
     * 同步订单工序数据
     *
     * @param synchronizerOrderContext
     * @param sysOrderPart
     * @param sheinPartCode
     */
    public void synchronizerOrderProcess(SynchronizerOrderContext synchronizerOrderContext, SysOrderPart sysOrderPart, String sheinPartCode) {
        try {
            // 判断是否已存在
            int count = this.orderProcessService.count(new LambdaQueryWrapper<SysOrderProcess>()
                    .eq(SysOrderProcess::getProduceOrderId, synchronizerOrderContext.getProduceOrderId())
                    .eq(SysOrderProcess::getPartCode, sheinPartCode)
            );
            if (count > 0) {
                log.debug("同步订单号：{}对应的部件：{} 的工序数据已存在,退出此次同步", synchronizerOrderContext.getProduceOrderId(), sheinPartCode);
                return;
            }

            // 创建部件工序信息
            createOrderProcesses(synchronizerOrderContext, sysOrderPart, sheinPartCode);
        } catch (Exception e) {
            log.error("同步订单号：{}对应的部件：{} 的工序数据失败", synchronizerOrderContext.getProduceOrderId(), sheinPartCode, e);
            throw new BusinessException(e.getMessage());
        }
    }

    /**
     * 创建部件工序信息
     *
     * @param synchronizerOrderContext
     * @param sysOrderPart
     * @param sheinPartCode
     * @return
     */
    private void createOrderProcesses(SynchronizerOrderContext synchronizerOrderContext, SysOrderPart sysOrderPart, String sheinPartCode) {
        QueryProduceOrderInfoByIdResDTO orderInfoByIdResDTO = synchronizerOrderContext.getOrderInfoById();

        // 获取工序费用信息
        ClothCostFeeDetail processCost = orderInfoByIdResDTO.getClothCostFeeDetail().stream().filter(x -> Objects.equals("加工费", x.getCategory())).findFirst().orElse(null);
        if (processCost == null || CollUtil.isEmpty(processCost.getClothCostFeeDetail())) {
            return;
        }

        // 保存部件工序信息
        SysOrderProcess sysOrderProcess = this.saveOrderProcess(synchronizerOrderContext, sysOrderPart, processCost, sheinPartCode);

        // 保存部件工序明细信息
        this.saveOrderProcessItems(sheinPartCode, sysOrderProcess.getId(), processCost);
    }


    /**
     * 保存部件工序信息
     *
     * @param synchronizerOrderContext
     * @param sysOrderPart
     * @param processCost
     * @return
     */
    private SysOrderProcess saveOrderProcess(SynchronizerOrderContext synchronizerOrderContext, SysOrderPart sysOrderPart, ClothCostFeeDetail processCost,
                                             String sheinPartCode) {
        // 倍率
        BigDecimal magnification = BigDecimal.valueOf(NumberUtil.nullToZero(processCost.getScale()));

        // 计算利润率
        double profitMargin = processCost.getClothCostFeeDetail().get(0).getProfitRate();

        // 利润率百分比
        double profitMarginPercentage = NumberUtil.mul(profitMargin, 100);

        // 构建工序对象
        SysOrderProcess sysOrderProcess = new SysOrderProcess();
        sysOrderProcess.setOrderId(synchronizerOrderContext.getOrderId());
        sysOrderProcess.setOrderPartId(sysOrderPart.getId());
        sysOrderProcess.setProduceOrderId(Convert.toStr(synchronizerOrderContext.getProduceOrderId()));
        sysOrderProcess.setPartCode(sheinPartCode);
        sysOrderProcess.setProfit(NumberUtil.round(profitMarginPercentage, 2).toPlainString());
        sysOrderProcess.setMagnification(NumberUtil.round(magnification, 2).toPlainString());
        sysOrderProcess.setCreateBy(OrderSynchronizedThreadLocal.getCreateBy());
        sysOrderProcess.setUpdateBy(OrderSynchronizedThreadLocal.getCreateBy());

        this.orderProcessService.save(sysOrderProcess);
        return sysOrderProcess;
    }


    /**
     * 保存工序明细
     *
     * @param sheinPartCode
     * @param processId
     * @param processCost
     * @return
     */
    private void saveOrderProcessItems(String sheinPartCode, Long processId, ClothCostFeeDetail processCost) {
        List<ClothCostFeeItem> clothCostFeeItems = processCost.getClothCostFeeDetail().stream().filter(x -> Objects.equals(StrUtil.nullToEmpty(x.getPartCode()), StrUtil.nullToEmpty(sheinPartCode))).collect(Collectors.toList());
        if (CollUtil.isEmpty(clothCostFeeItems)) {
            return;
        }

        List<SysOrderProcessItem> processItems = new ArrayList<>();
        for (ClothCostFeeItem clothCostFeeItem : clothCostFeeItems) {
            SysOrderProcessItem sysOrderProcessItem = new SysOrderProcessItem();
            sysOrderProcessItem.setOrderProcessId(processId);
            sysOrderProcessItem.setProcessName(clothCostFeeItem.getTitle());
            sysOrderProcessItem.setWage(StrUtil.toString(clothCostFeeItem.getUnitPrice()));
            sysOrderProcessItem.setCreateBy(OrderSynchronizedThreadLocal.getCreateBy());
            sysOrderProcessItem.setUpdateBy(OrderSynchronizedThreadLocal.getCreateBy());
            processItems.add(sysOrderProcessItem);
        }
        this.orderProcessItemService.saveBatch(processItems);
    }


}
